package com.projles.ttd.minigames;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Color;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.TextView;

import com.projles.ttd.OpcoesActivity;
import com.projles.ttd.R;
import com.projles.ttd.dados.BDAdapter;
import com.projles.ttd.util.Jogador;
import com.projles.ttd.util.Player;
import com.projles.ttd.util.Questao;

public class MiniGameQuizActivity extends Activity implements OnClickListener {
	
    private Questao questaoGerada = null;
    private Integer numeroRodadas;
    private Integer NUM_RODADAS_DEFAULT = 3;
    
    private final Integer NUM_ALTERNATIVAS = 4;
    private final Integer TEMPO_LIMITE_PARA_RESPONDER = 15000; //em milisegundos
    
    private final Integer PERGUNTA_COL = 0;
    private final Integer ALTERNATIVA_A_COL = 1;
    private final Integer ALTERNATIVA_B_COL = 2;
    private final Integer ALTERNATIVA_C_COL = 3;
    private final Integer ALTERNATIVA_D_COL = 4;
    private final Integer RESPOSTA_COL = 5;
    
    private Integer indiceJogadorAtual;
    private Jogador jogadorAtual;
	
    private CountDownTimer countdown;
    private TextView countdownView;
    private TextView saudacaoView;
    private TextView perguntaView;
    private TextView statusView;
    private List<TextView> alternativasView;
    private View viewParaAnimar;
    
    private BDAdapter bdAdapter;
    private Player player;
    
	private List<Jogador> jogadores = new ArrayList<Jogador>();
	private List<Questao> questoesDisponiveis = new ArrayList<Questao>();
	
	private boolean travado = false;
	
	@SuppressWarnings("unchecked")
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
    	//Pegando os parametros da Intent passados na Activity anterior
    	Bundle params = getIntent().getExtras();
    	
    	jogadores = (ArrayList<Jogador>) params.get("jogadores");
    	indiceJogadorAtual = -1;
    	
    	limpaPontuacaoJogadores();

		bdAdapter = new BDAdapter(this);
    	bdAdapter.open();
    	
    	SharedPreferences config = getSharedPreferences(OpcoesActivity.PREFS_NAME, 0);
        numeroRodadas = config.getInt("num_rodadas", NUM_RODADAS_DEFAULT);
    	
    	player = Player.getPlayer(this);
	}

	@Override
	public void onStart() {
		super.onStart();
		
		setContentView(R.layout.minigame_quiz_novo);
		
    	atualizarJogadorAtual();
    	carregaViews();
    	configuraCronometro();

		animarEntradaView();
		
		questaoGerada = pegarQuestaoAleatoria();
		Collections.shuffle(questaoGerada.getAlternativas());
		
		countdownView.setTextColor(Color.WHITE);
		saudacaoView.setText(getResources().getString(R.string.txt_jogador_vez) +" "+ jogadores.get(indiceJogadorAtual).getNome());
		statusView.setText( getResources().getString(R.string.txt_erros) +" "+ jogadorAtual.getErros() +"  "+ getResources().getString(R.string.txt_acertos) +" "+ jogadorAtual.getAcertos());
		perguntaView.setText(questaoGerada.getPergunta());
		
		for (int i = 0; i < NUM_ALTERNATIVAS; i++) {
			alternativasView.get(i).setText(questaoGerada.getAlternativas().get(i));
		}
		
		countdown.cancel();
		
		if (!travado) {
			countdown.start();
		}
	}
	
	@Override
	public void onStop() {
		countdown.cancel();
		bdAdapter.close();
		travado = true;
		super.onStop();
	}
	
	
	
	@Override
	protected void onDestroy() {
		countdown.cancel();
		bdAdapter.close();
		travado = true;
		super.onDestroy();
	}

	@Override
	protected void onPause() {
		countdown.cancel();
		bdAdapter.close();
		travado = true;
		super.onPause();
	}

	private void carregaViews() {
		countdownView = (TextView) findViewById(R.id.countdown_quiz);
    	saudacaoView = (TextView) findViewById(R.id.saudacao_quiz);
    	statusView = (TextView) findViewById(R.id.status_quiz);
    	perguntaView = (TextView) findViewById(R.id.pergunta_quiz);
    	viewParaAnimar = findViewById(R.id.layout_externo_quiz);
    	gerarViewsParaAlternativas();
	}

	private void configuraCronometro() {
		countdown = new CountDownTimer(TEMPO_LIMITE_PARA_RESPONDER, 500) {
			
			@Override
			public void onTick(long tempoRestante) {
				countdownView.setText(getResources().getString(R.string.txt_tempo) +" "+ tempoRestante/1000);
				if (tempoRestante/1000 < 4) {
					countdownView.setTextColor(Color.RED);
				}
			}
			
			@Override
			public void onFinish() {
				jogadorAtual.errou();
				player.doh();
				
				setContentView(R.layout.fim_do_tempo);
				
				Handler handler = new Handler(); 
				handler.postDelayed(new Runnable() { 
					public void run() {
						novaRodada();
					} 
				}, 1000);

			}
		};
	}
	
	
	
	private void limpaPontuacaoJogadores() {
		
		for(Jogador j : jogadores) {
			j.zerarErrosAcertos();
		}
	}
	
	private void gerarViewsParaAlternativas() {
		alternativasView = new ArrayList<TextView>();
		alternativasView.add((Button) findViewById(R.id.a));
		alternativasView.add((Button) findViewById(R.id.b));
		alternativasView.add((Button) findViewById(R.id.c));
		alternativasView.add((Button) findViewById(R.id.d));

		for (int i = 0; i < NUM_ALTERNATIVAS; i++) {
			alternativasView.get(i).setOnClickListener(this);
		}
	}
	
	private Questao pegarQuestaoAleatoria() {
    	if (questoesDisponiveis.isEmpty()) {
    		questoesDisponiveis = getAllQuestoes();
    	}
    	
    	Random rd = new Random();
    	int indice = rd.nextInt(questoesDisponiveis.size());
    	Questao questao = questoesDisponiveis.get(indice);
    	questoesDisponiveis.remove(indice);
		return questao;
	}
    
    private List<Questao> getAllQuestoes() {
    	Cursor questoesCursor = bdAdapter.getAllQuestoes();
    	List<Questao> questoes = new ArrayList<Questao>();
            questoesCursor.moveToFirst();
            while (questoesCursor.isAfterLast() == false) {
            	String pergunta = questoesCursor.getString(PERGUNTA_COL);
            	String[] alternativasArray = {
            	questoesCursor.getString(ALTERNATIVA_A_COL),
            	questoesCursor.getString(ALTERNATIVA_B_COL),
            	questoesCursor.getString(ALTERNATIVA_C_COL),
            	questoesCursor.getString(ALTERNATIVA_D_COL) };
            	
            	String resposta = questoesCursor.getString(RESPOSTA_COL);
                
                Questao q = new Questao(pergunta, resposta, new ArrayList<String>(Arrays.asList(alternativasArray)));
           	    questoes.add(q);
                questoesCursor.moveToNext();
            }
            questoesCursor.close();
		return questoes;
    }

    private void atualizarJogadorAtual() {
    	if (indiceJogadorAtual == jogadores.size() - 1) {
    		indiceJogadorAtual = 0;
    	} else {
    		indiceJogadorAtual++;
    	}
    	
    	jogadorAtual = jogadores.get(indiceJogadorAtual);
    }
    
    
	private void animarEntradaView() {
    	Animation in = AnimationUtils.makeInChildBottomAnimation(this);
    	viewParaAnimar.startAnimation(in);
    	viewParaAnimar.setVisibility(View.VISIBLE);
	}

	private boolean usuarioAcertou(TextView view) {
		// o view.getText() retorna uma string do tipo 1) quest�o. Substring(3) remove 
		// esses tres primeiros caracters para comparar o chute com a resposta do bd
		String chute = ((String) view.getText()).trim(); 
		if (chute.equals(questaoGerada.getResposta())) {
			return true;
		}
		return false;
	}
	
    private boolean terminou() {
    	if (jogadorAtual.equals(jogadores.get(jogadores.size() - 1))) {
    		Integer numRodadas = jogadorAtual.getAcertos() + jogadorAtual.getErros();
    		
    		//Se o ultimo jogador da sequencia tiver jogado NUM_RODADAS vezes
    		if (numRodadas == numeroRodadas) {
    			return true; 
    		}
    	}
    	return false;
    }
    
    private void novaRodada() {
    	if (!terminou()) {
    		countdown.cancel();
    		onStart();
    	} else {
    		resultadoJogo();
    	}
    }
    
    
    private void resultadoJogo(){
    	
    	boolean empate = false;
    	
    	Jogador jogadorQueErrouMais = jogadores.get(0);
    	
    	for (int i = 1; i < jogadores.size(); i++) {

    		Jogador j = jogadores.get(i); 
    		
    		if (j.getErros() > jogadorQueErrouMais.getErros()) {
    			empate = false;
    			jogadorQueErrouMais = j;
    		}
    		else if (j.getErros() == jogadorQueErrouMais.getErros()) {
    			empate = true;
    		}
			
		}
    	
    	
    	if (empate) {
    		
    		setContentView(R.layout.tela_empate);
    		
    		Handler handler = new Handler(); 
    		handler.postDelayed(new Runnable() { 
    			public void run() {
    				finalizaMinigame();
    			} 
    		}, 2000); 

    	}
    	else {
    		jogadorQueErrouMais.addDerrota();
    	    player.aplausos();
    	    
    	    setContentView(R.layout.tela_bebe);
    	    TextView qmBebe = (TextView) findViewById(R.id.txt_qm_bebe);
    	    qmBebe.setText(jogadorQueErrouMais.getNome() +"\n\n"+ getResources().getString(R.string.txt_bebe));
    	    
    		Handler handler = new Handler(); 
    	    handler.postDelayed(new Runnable() { 
    	         public void run() {
    	       		finalizaMinigame();
    	         } 
    	    }, 2000); 
    	}
    }
    
    
    private void finalizaMinigame() {
    	Intent i = this.getIntent();
		i.putExtra("listaAtualizada", (Serializable) jogadores);
		this.setResult(RESULT_OK, i);
		
		bdAdapter.close();
		finish();
	}
    
	@Override
	public void onClick(View viewClicada) {
		boolean acertou = false;
		player.click();
		
		switch (viewClicada.getId()) {
		case R.id.a:
			acertou = usuarioAcertou(alternativasView.get(0));
			break;
		case R.id.b:
			acertou = usuarioAcertou(alternativasView.get(1));
			break;
		case R.id.c:
			acertou = usuarioAcertou(alternativasView.get(2));
			break;
		case R.id.d:
			acertou = usuarioAcertou(alternativasView.get(3));
			break;
		default:
			break;
		}
		
		
		countdown.cancel();
		
		if (acertou) {
			jogadorAtual.acertou();
			player.excellent();
			
			setContentView(R.layout.acertou);
			
			Handler handler = new Handler(); 
			handler.postDelayed(new Runnable() { 
				public void run() {
					novaRodada();
				} 
			}, 1000); 
			
		} else {
			jogadorAtual.errou();
			player.doh();

			setContentView(R.layout.errou);
			
			Handler handler = new Handler(); 
			handler.postDelayed(new Runnable() { 
				public void run() {
					novaRodada();
				} 
			}, 1000); 
		}
		
	}
	
}
